import { Component, OnInit, Inject, OnDestroy } from "@angular/core";

import {
  ISelectSymbolResponse,
  IMu,
  IZi,
  IQuerySymbol,
  IOnSymbol
} from "@/trade/store/models/trade";
import * as fromTrade from "@/trade/store/reducers/index";
import { Store, select } from "@ngrx/store";
import { TradeActions } from "@/trade/store/actions";
import { map, filter } from "rxjs/operators";
import { Subscription, BehaviorSubject } from "rxjs";
import { ActivatedRoute } from "@angular/router";
import { Router, NavigationEnd } from "@angular/router";
import { takeUntil, mergeMap } from "rxjs/operators";
import { forkJoin, combineLatest } from "rxjs";
import { FormControl } from "@angular/forms";
import * as fromRoot from "@/reducers";

import {
  LocaleService,
  TranslationService,
  Language,
  DefaultLocale
} from "angular-l10n";

interface ITrade {
  time: number;
  type: "SELL" | "BUY";
  price: string;
  amount: string;
}

@Component({
  selector: "app-panel-trade",
  templateUrl: "./panel-trade.component.html",
  styleUrls: ["./panel-trade.component.scss"]
})
export class PanelTradeComponent implements OnInit, OnDestroy {
  @Language() lang: string;

  tv = {
    mu: {
      symbol: "BTC"
    }
  };

  tradeLists: Array<ITrade> = [];

  timer = null;

  symbolMap$ = this.store
    .pipe(select(fromRoot.symbolMap))
    .pipe(filter(symbolMap => !!symbolMap));

  sub$ = {
    queryAndConnected$: null,
    trade$: null,
    symbolMapSub$: null
  };

  querySymbol: IQuerySymbol;

  onSymbol = {
    h: "0.0000",
    l: "0.0000",
    v: "0.0000",
    lastPrice: "0.0000",
    change: "0.00",
    symbol: "",
    sort: 0,
    isLove: false,
    type: "",
    mu: "",
    zi: ""
  };

  // move to service
  @DefaultLocale() defaultLocale: string;

  constructor(
    @Inject("UtilsService") private utilsService,
    @Inject("SkService") private skService,
    private activatedRoute: ActivatedRoute,
    private store: Store<fromTrade.State | fromRoot.State>
  ) {}

  ngOnInit() {
    this.addListen();
  }

  formatTrade(arr) {
    return arr.slice().map(d => {
      return {
        time: d.createtime,
        type: d.takerOrderId === d.askOrderId ? "SELL" : "BUY",
        price: this.utilsService.formatNumPoint(d.price),
        amount: this.utilsService.formatNumPoint(d.amount)
      };
    });
  }

  addListen() {
    this.sub$.symbolMapSub$ = combineLatest(
      this.symbolMap$,
      this.activatedRoute.queryParams
    ).subscribe(([symbolMap, query]) => {
      const { symbol } = query;
      this.querySymbol = this.utilsService.splitQuerySymbol(symbol);
      const onSymbol =
        symbolMap[`${this.querySymbol.zi}${this.querySymbol.mu}`];
      if (!!onSymbol) {
        this.onSymbol = onSymbol;
      }
    });

    this.sub$.queryAndConnected$ = combineLatest(
      this.activatedRoute.queryParams,
      this.skService.connected$
    ).subscribe(([query, connected]) => {
      const [zi, mu] = query.symbol.split("_");
      if (connected) {
        this.utilsService.unsub({ trade$: this.sub$.trade$ });
        this.tradeLists = [];
        this.sub$.trade$ = this.skService
          .sub(`/topic/trade/${zi}_${mu}`)
          .subscribe(res => {
            // 更新 24 ticker
            this.store.dispatch(
              new TradeActions.SelectSymbol({
                req: undefined
              })
            );

            let data = JSON.parse(JSON.parse(res.body).responseMessage);

            const isPush =
              Object.prototype.toString.call(data) === "[object Object]";

            if (isPush) {
              data = this.tradeLists.slice().concat(this.formatTrade([data]));
            } else {
              data = this.tradeLists.slice().concat(this.formatTrade(data));
            }

            // here format move to format service
            this.tradeLists = data.slice(0, 50).sort((pre, next) => {
              return Number(next.time) - Number(pre.time);
            });
          });
      }
    });
  }

  ngOnDestroy() {
    this.utilsService.unsub(this.sub$);
  }
}
